package com.googlecode.c4e.ui.views.internal;

import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
import org.eclipse.ui.progress.IElementCollector;

import com.googlecode.c4e.api.Registry;
import com.googlecode.c4e.api.model.ProjectGroup;
import com.googlecode.c4e.api.model.Server;
import com.googlecode.c4e.ui.ContinuumPlugin;
import com.googlecode.c4e.ui.internal.preferences.IPreferenceIds;
import com.googlecode.c4e.ui.views.ServersView;

public class ServerAdapter implements IDeferredWorkbenchAdapter {

	public Object[] getChildren(Object obj) {
		Server server = (Server) obj;
		if (server.getProjectGroups() != null) {
			return server.getProjectGroups().toArray();
		}
		try {
			server.setProjectGroups(Registry.getDefault().listProjectGroups(
					server));
		} catch (Exception e) {
			ContinuumPlugin.getDefault().log("listProjectGroups", e);
			return new Object[0];
		}
		return server.getProjectGroups().toArray();
	}

	public ImageDescriptor getImageDescriptor(Object arg0) {
		return ContinuumPlugin.getDefault().getImageDescriptor("continuum");
	}

	public String getLabel(Object obj) {
		Server server = (Server) obj;
		return server.getLabel();
	}

	public Object getParent(Object arg0) {
		return null;
	}

	public void fetchDeferredChildren(Object obj, IElementCollector collector,
			IProgressMonitor monitor) {
		Server server = (Server) obj;
		String layout = ContinuumPlugin.getDefault().getPreferenceStore()
				.getString(IPreferenceIds.SERVERS_VIEW_PRESENTATION);
		if (layout == null || !layout.equals(ServersView.FLAT)) {
			monitor.beginTask("Fetching groups for " + server.getLabel(), 100);

			if (server.getProjectGroups() != null) {
				collector.add(server.getProjectGroups().toArray(), monitor);
				monitor.done();
				return;
			}

			if (server.isAvailable()) {
				try {
					server.setProjectGroups(Registry.getDefault()
							.listProjectGroups(server));
				} catch (Exception e) {
					monitor.done();
					throw new RuntimeException(e);
				}
				collector.add(server.getProjectGroups().toArray(), monitor);
			}
			monitor.done();
		} else {
			if (server.isAvailable()) {
				monitor.beginTask("Fetching projects for " + server.getLabel(),
						100);

				if (server.getProjectGroups() == null) {
					try {
						server.setProjectGroups(Registry.getDefault()
								.listProjectGroups(server));
					} catch (Exception e) {
						monitor.done();
						throw new RuntimeException(e);
					}
				}
				try {
					List<ProjectGroup> groups = server.getProjectGroups();
					for (int i = 0; i < groups.size(); i++) {
						ProjectGroup group = groups.get(i);
						monitor.subTask("Fetching projects for "
								+ group.getName());
						if (group.getProjects() == null) {
							group.setProjects(Registry.getDefault()
									.listProjects(group));
						}
						collector.add(group.getProjects().toArray(), monitor);
						monitor.worked(100 / groups.size());
					}
				} catch (Exception e) {
					monitor.done();
					throw new RuntimeException(e);
				}
			}
			monitor.done();
		}

	}

	public ISchedulingRule getRule(Object obj) {
		Server server = (Server) obj;
		return new ServerAdapterSchedulingRule(server);
	}

	public boolean isContainer() {
		return true;
	}

}
